<?php

class iSpringRestClient extends RestClient
{
    const GET_STORE_ID                  = '/shopping_cart/store/{host}';
    const PRICES_PATH                   = '/store/{store_id}/products/prices/{type}';

    const PRODUCT_PATH                  = '/product/{prod-id}';
    const PRODUCTS_PATH                 = '/products';
    const PRODUCTS_ACTUAL_PATH          = '/products/actual';

    const SEND_MAIL_PATH                = '/send_mail';
    const CREATE_LICENSE_PATH           = '/license';

    private $baseUrl = null;

    public function __construct( $baseUrl )
    {
        $this->SetUrl( $baseUrl );
    }

    public function SetUrl( $url )
    {
        $url = rtrim($url, "/");
        $this->baseUrl = $url;
    }

    public function GetUrl()
    {
        return $this->baseUrl;
    }

    public function GetStoreId($host)
    {
        $url = $this->baseUrl . self::GET_STORE_ID;
        $url = str_replace('{host}', urlencode($host), $url);

        $res = $this->SendRequest($url, array(), RequestMethod::GET);

        $storeId = null;
        if ($res->code == HttpStatus::OK && !empty($res->data))
        {
            $doc = Util::CreateXmlDocument($res->data);
            if ($doc)
            {
                $xpathHelper = new XPathHelper($doc);
                $storeId = $xpathHelper->GetText("/success/store_id");
            }
        }

        if (!$storeId)
        {
            $methodExecuteInfo = array(
                "request_params" => array(),
                "request_url" => $url,
                "response_code" => $res->code,
                "response_data" => $res->data
            );
            throw new ServiceRuntimeException(__CLASS__ . "::" . __METHOD__ . ' - Unknown host.', $methodExecuteInfo);
        }

        return $storeId;
    }

    public function GetProductInfo( $prodId, &$etag = null )
    {
        $url = $this->baseUrl . self::PRODUCT_PATH;
        $url = str_replace('{prod-id}', $prodId, $url);

        $headers = array();
        if ( !empty($etag) )
        {
            $headers[] = "ETag: $etag";
        }
        $res = $this->SendRequest( $url, '', RequestMethod::GET, $headers );

        if ( $res->code == HttpStatus::NOT_MODIFIED )
        {
            return null;
        }

        $productInfo = null;
        $etag = null;

        if ( $res->code == HttpStatus::OK && !empty($res->data) )
        {
            $doc = Util::CreateXmlDocument( $res->data );
            if ( $doc )
            {
                $productInfo = new ProductInfo();
                $productInfo->Parse( new XPathHelper($doc) );
                $etag = $res->headers['ETag'];
            }
        }
        return $productInfo;
    }

    public function GetProductsInfo( $prodId = null, &$etag = null )
    {
        $url = $this->baseUrl . self::PRODUCTS_PATH;
        if ( !is_null($prodId) )
        {
            $url .= "/$prodId";
        }

        $headers = array();
        if ( !empty($etag) )
        {
            $headers[] = "ETag: $etag";
        }
        $res = $this->SendRequest( $url, '', RequestMethod::GET, $headers );

        if ( $res->code == HttpStatus::NOT_MODIFIED )
        {
            return null;
        }

        $etag = null;
        $result = array();
        if ( $res->code == HttpStatus::OK && !empty($res->data) )
        {
            $doc = Util::CreateXmlDocument( $res->data );
            if ( $doc )
            {
                $xpathHelper = new XPathHelper($doc);

                $nodes = $xpathHelper->GetNodes("/Products/Product");
                foreach ( $nodes as $node )
                {
                    $xpathHelper->curNode = $node;
                    $productInfo = new ProductInfo();
                    $productInfo->Parse( $xpathHelper );
                    $result[] = $productInfo;
                }
                $etag = $res->headers['ETag'];
            }
        }
        return $result;
    }

    /**
    *
    * @param string $priceType One of the PriceType value
    * @param string $storeId Store Id
    * @return array An array of array of PriceInfo objects by products
    */
    public function GetProductsPrices( $priceType, $storeId )
    {
        $url = $this->baseUrl . self::PRICES_PATH;
        $url = str_replace('{type}', $priceType, $url);
        $url = str_replace('{store_id}', $storeId, $url);

        $res = $this->SendRequest( $url, null, RequestMethod::GET );

        $result = array();
        if ( $res->code == HttpStatus::OK && !empty($res->data) )
        {
            $doc = Util::CreateXmlDocument( $res->data );
            if ( $doc )
            {
                $xpathHelper = new XPathHelper($doc);

                $nodes = $xpathHelper->GetNodes("price_info");
                foreach ( $nodes as $node )
                {
                    $xpathHelper->curNode = $node;
                    $priceInfo = new PriceInfo();
                    $priceInfo->Parse( $xpathHelper );

                    if ( !isset( $result[ $priceInfo->product ] ) )
                    {
                        $result[ $priceInfo->product ] = array();
                    }

                    $result[ $priceInfo->product ][ $priceInfo->volume ] = $priceInfo;
                }
            }
        }

        return $result;
    }

    public function GetProductsActual( &$etag = null)
    {
        $url = $this->baseUrl . self::PRODUCTS_ACTUAL_PATH;

        $headers = array();
        if ( !empty($etag) )
        {
            $headers[] = "ETag: $etag";
        }
        $res = $this->SendRequest( $url, '', RequestMethod::GET, $headers );

        if ( $res->code == HttpStatus::NOT_MODIFIED )
        {
            return null;
        }

        $etag = null;
        $result = array();

        if ( $res->code == HttpStatus::OK && !empty($res->data) )
        {
            $doc = Util::CreateXmlDocument( $res->data );
            if ( $doc )
            {
                $xpathHelper = new XPathHelper($doc);

                $nodes = $xpathHelper->GetNodes("/ActualProducts/Product");
                foreach ( $nodes as $node )
                {
                    $xpathHelper->curNode = $node;
                    $productInfo = new ProductInfo();
                    $productInfo->Parse( $xpathHelper );
                    $result[] = $productInfo;
                }
                $etag = $res->headers['ETag'];
            }
        }
        return $result;
    }

    public function SendMail( MailMessage $msg, $timeOffset = null )
    {
        $url = $this->baseUrl . self::SEND_MAIL_PATH;

        $params = (array) $msg;
        if (!empty($timeOffset) && is_numeric($timeOffset))
        {
            $params['time_offset'] = $timeOffset;
        }

        $res = $this->SendRequest( $url, $params, RequestMethod::POST );

        if ( $res->code == HttpStatus::BAD_REQUEST )
        {
            $errorMessage = '';
            if ( !empty($res->data) )
            {
                $doc = Util::CreateXmlDocument( $res->data );
                if ( $doc )
                {
                    $xpathHelper = new XPathHelper($doc);
                    $errorMessage = $xpathHelper->GetText("/SendMail/Error");
                }
            }
            throw new MailSendException($errorMessage);
        }
    }

    public function CreateLicense(
        $gate, $product, $license,  $version, $name,
        $email = null, $phone = null, $ip_address = null, $uid = null, $company = null,
        $web = null, $country = null, $quantity = null, $total = null,
        $order_id = null, $password = null, $upgrade = null, $subscribed = true
    )
    {
        $pnames = array();
        if (!is_null($email))       $pnames[] = 'email';
        if (!is_null($company))     $pnames[] = 'company';
        if (!is_null($web))         $pnames[] = 'web';
        if (!is_null($country))     $pnames[] = 'country';
        if (!is_null($quantity))    $pnames[] = 'quantity';
        if (!is_null($total))       $pnames[] = 'total';
        if (!is_null($order_id))    $pnames[] = 'order_id';
        if (!is_null($password))    $pnames[] = 'password';
        if (!is_null($upgrade))     $pnames[] = 'upgrade';
        if (!is_null($ip_address))  $pnames[] = 'ip_address';
        if (!is_null($uid))         $pnames[] = 'uid';
        if (!is_null($phone))       $pnames[] = 'phone';

        $params = compact( "subscribed", "gate", "product", "license", "version", "name", $pnames );
        $url = $this->baseUrl . self::CREATE_LICENSE_PATH;
        $res = $this->SendRequest( $url, $params, RequestMethod::POST );

        $serial = null;
        if ( $res->code == HttpStatus::OK && !empty($res->data) )
        {
            $doc = Util::CreateXmlDocument( $res->data );
            if ( $doc )
            {
                $xpathHelper = new XPathHelper($doc);
                $serial = $xpathHelper->GetText("/CreateLicense/Serial");
            }
        }
        return $serial;
    }
}

?>